package com.example.websocket.aop.config;

import com.example.websocket.aop.config.annotation.MyAopAnnotation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.sql.SQLException;

@Aspect
@Component
public class AopAdvice {

    @Resource
    private ConnectionUtils connectionUtils;

    @Pointcut("execution (* com.example.websocket.aop.controller.*.*(..))")
    public void test() {
        System.out.println("pointcut签名");
    }

//    @Before("test()")
//    public void beforeAdvice() {
//        System.out.println("beforeAdvice...");
//    }

//    @After("test()")
//    public void afterAdvice() {
//        System.out.println("afterAdvice...");
//    }

    public void beginTransaction() {
        try {
            connectionUtils.getThreadConnection().setAutoCommit(false);
            System.out.println("开启事务");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public void commit() {
        try {
            connectionUtils.getThreadConnection().commit();
            System.out.println("提交事务");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public void rollback() {
        try {
            connectionUtils.getThreadConnection().rollback();
            System.out.println("事务回滚");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public void release() {
        try {
            connectionUtils.getThreadConnection().close();
            connectionUtils.removeConnection();
            System.out.println("释放资源");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    @Around("test()")
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        try {
            System.out.println("before");
            this.beginTransaction();
            Signature signature = proceedingJoinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method =methodSignature.getMethod();
            MyAopAnnotation annotation = method.getAnnotation(MyAopAnnotation.class);
            if (annotation == null) return;
            System.out.println(annotation.value());
            proceedingJoinPoint.proceed();
            this.commit();
        } catch (Throwable t) {
            this.rollback();
            t.printStackTrace();
        }
        this.release();
        System.out.println("after");
    }
}
